package com.zhongke.common.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.GradientDrawable
import android.view.View
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.roundToInt

/**
 * @author: ZhangQingHua
 * @date: 2021/11/26
 * @description
 *
 * 列表分隔符，支持纵向和横向
 *
 * @param orientation VERTICAL-纵向 HORIZONTAL-横向
 * @param size 分隔符的粗细，纵向时为高度，横向时为宽度
 * @param colorRes 分隔符的颜色资源 Id，默认为透明
 * @param leftMargin 分隔符的左边距，横向时不生效
 * @param rightMargin 分隔符的右边距，横向时不生效
 * @param includeEdge 最后一个列表项是否绘制分隔符
 *
 */
class ItemDivider(
    context: Context,
    private val orientation: Int = VERTICAL,
    size: Int,
    @ColorRes
    private val colorRes: Int = -1,
    @ColorInt
    private val leftMargin: Int = 0,
    private val rightMargin: Int = 0,
    private val includeEdge: Boolean = false
) : RecyclerView.ItemDecoration() {

    companion object {
        const val VERTICAL = 1
        const val HORIZONTAL = 2
    }

    private val mBounds = Rect()
    private val mDivider: GradientDrawable = GradientDrawable()

    init {
        mDivider.setColor(if (colorRes == -1) Color.TRANSPARENT else ContextCompat.getColor(context, colorRes))
        if (orientation == VERTICAL) {
            mDivider.setSize(0, size)
        } else {
            mDivider.setSize(size, 0)
        }
    }

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        if (orientation == VERTICAL) {
            drawVertical(c, parent)
        } else {
            drawHorizontal(c, parent)
        }
    }

    private fun drawVertical(canvas: Canvas, parent: RecyclerView) {
        canvas.save()
        val left: Int
        val right: Int
        if (parent.clipToPadding) {
            left = parent.paddingLeft + leftMargin
            right = parent.width - parent.paddingRight - rightMargin
            canvas.clipRect(
                left, parent.paddingTop, right,
                parent.height - parent.paddingBottom
            )
        } else {
            left = 0
            right = parent.width
        }
        val childCount = parent.childCount
        for (i in 0 until childCount) {
            if (i == childCount - 1 && !includeEdge) {
                break
            }
            val child = parent.getChildAt(i)
            parent.getDecoratedBoundsWithMargins(child, mBounds)
            val bottom = mBounds.bottom + child.translationY.roundToInt()
            val top: Int = bottom - mDivider.intrinsicHeight
            mDivider.setBounds(left, top, right, bottom)
            mDivider.draw(canvas)
        }
        canvas.restore()
    }

    private fun drawHorizontal(canvas: Canvas, parent: RecyclerView) {
        canvas.save()
        val top: Int
        val bottom: Int
        if (parent.clipToPadding) {
            top = parent.paddingTop
            bottom = parent.height - parent.paddingBottom
            canvas.clipRect(
                parent.paddingLeft, top,
                parent.width - parent.paddingRight, bottom
            )
        } else {
            top = 0
            bottom = parent.height
        }
        val childCount = parent.childCount
        for (i in 0 until childCount) {
            if (i == childCount - 1 && !includeEdge) {
                break
            }
            val child = parent.getChildAt(i)
            parent.layoutManager!!.getDecoratedBoundsWithMargins(child, mBounds)
            val right = mBounds.right + child.translationX.roundToInt()
            val left = right - mDivider.intrinsicWidth
            mDivider.setBounds(left, top, right, bottom)
            mDivider.draw(canvas)
        }
        canvas.restore()
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val adapter = parent.adapter ?: return
        val isLast = parent.getChildAdapterPosition(view) == adapter.itemCount - 1

        if (orientation == DividerItemDecoration.VERTICAL) {
            outRect[0, 0, 0] = mDivider.intrinsicHeight
        } else {
            outRect[0, 0, mDivider.intrinsicWidth] = 0
        }

        if (isLast && !includeEdge) {
            outRect.set(0, 0, 0, 0)
        }
    }
}